home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Milan_1991 / Devcon91.4 / AppShell / Examples / ILBMer / ilbmer.c next >
Encoding:
C/C++ Source or Header  |  1992-09-01  |  57.3 KB  |  2,223 lines

  1. /*************************************************************************
  2.   *                                                                      *
  3.   *                            Preliminary                               *
  4.   *                        Amiga AppShell (tm)                           *
  5.   *                                                                      *
  6.   *  Copyright (c) 1990,1991 Commodore-Amiga, Inc. All Rights Reserved.  *
  7.   *                                                                      *
  8.   *   This software and information is proprietary, preliminary, and     *
  9.   *   subject to change without notice.                                  *
  10.   *                                                                      *
  11.   *                            DISCLAIMER                                *
  12.   *                                                                      *
  13.   *   THIS SOFTWARE IS PROVIDED "AS IS".                                 *
  14.   *   NO REPRESENTATIONS OR WARRANTIES ARE MADE WITH RESPECT TO THE      *
  15.   *   ACCURACY, RELIABILITY, PERFORMANCE, CURRENTNESS, OR OPERATION      *
  16.   *   OF THIS SOFTWARE, AND ALL USE IS AT YOUR OWN RISK.                 *
  17.   *   NEITHER COMMODORE NOR THE AUTHORS ASSUME ANY RESPONSIBILITY OR     *
  18.   *   LIABILITY WHATSOEVER WITH RESPECT TO YOUR USE OF THIS SOFTWARE.    *
  19.   *                                                                      *
  20.   *                          Non-Disclosure                              *
  21.   *                                                                      *
  22.   *   This information is not to be disclosed to any other company,      *
  23.   *   individual or party.  Discussion is to be restricted to CBM        *
  24.   *   approved discussion areas, such as the closed conferences on bix;  *
  25.   *   amiga.cert, amiga.com, amiga.beta/appshell.                        *
  26.   *                                                                      *
  27.   ************************************************************************
  28.   */
  29.  
  30. /* ILBMer.c
  31.  * Copyright (C) 1990, 1991 Commodore-Amiga, Inc.
  32.  * Written by David N. Junod
  33.  *
  34.  * This is an example of an AppShell application.  It allows you to
  35.  * load an ILBM from a file or clipboard, display it, copy it to the
  36.  * clipboard, and save it as a 'C' source file in image or sprite format.
  37.  *
  38.  * It fully supports the ARexx, Command Shell, Intuition and Workbench
  39.  * user interfaces.
  40.  *
  41.  */
  42.  
  43. #include <exec/types.h>
  44. #include <exec/lists.h>
  45. #include <exec/nodes.h>
  46. #include <exec/memory.h>
  47. #include <utility/hooks.h>
  48. #include <graphics/scale.h>
  49. #include <graphics/displayinfo.h>
  50. #include <intuition/intuition.h>
  51. #include <intuition/intuitionbase.h>
  52. #include <intuition/classes.h>
  53. #include <intuition/classusr.h>
  54. #include <libraries/asl.h>
  55. #include <libraries/appshell.h>
  56. #include <libraries/gadtools.h>
  57. #include <libraries/prefs.h>
  58. #include <workbench/workbench.h>
  59. #include <workbench/startup.h>
  60. #include <clib/macros.h>
  61. #include <clib/asl_protos.h>
  62. #include <clib/dos_protos.h>
  63. #include <clib/exec_protos.h>
  64. #include <clib/icon_protos.h>
  65. #include <clib/intuition_protos.h>
  66. #include <clib/gadtools_protos.h>
  67. #include <clib/graphics_protos.h>
  68. #include <clib/appshell_protos.h>
  69. #include <clib/appobjects_protos.h>
  70. #include <clib/utility_protos.h>
  71. #include <pragmas/exec.h>
  72. #include <pragmas/dos.h>
  73. #include <pragmas/appshell.h>
  74. #include <pragmas/appobjects.h>
  75. #include <pragmas/utility.h>
  76. #include <pragmas/asl.h>
  77. #include <string.h>
  78. #include "ae:support/misc_protos.h"
  79. #include "ae:clipboard/clipiff.h"
  80.  
  81. /* Output of bumprev */
  82. #include "ilbmer.h"
  83.  
  84. /* Icon that we use for listings */
  85. extern struct DiskObject Listing;
  86.  
  87. /* The AppShell maintains some basic information on the application.  This
  88.  * information would appear in the About requester, and in AppExchange. */
  89. #define    APPBASE "ILBMER"
  90. #define    APPNAME "ILBMer"
  91. #define    APPVERS    VERS
  92. #define    APPCOPY "Copyright (C) 1990,1991 Commodore-Amiga, Inc."
  93. #define    APPAUTH "Written by David N. Junod"
  94.  
  95. char *version = VERSTAG;
  96.  
  97. /* File requester ID's. */
  98. #define    FR_ILBM    0
  99. #define    FR_C    1
  100. #define    FR_MAX    2
  101.  
  102. /* This structure contains all the data that our application will need.
  103.  * Change to suit your application. */
  104. struct AppData
  105. {
  106.     struct FileRequester *ad_FR[FR_MAX];    /* File requesters */
  107.     struct ClipManager *ad_CM;    /* Clipboard manager handle */
  108.     struct Image ad_Image;    /* Image... */
  109.     struct PointerPref *ad_Ptr;    /* Pointer... */
  110.     ILBM *ad_IR;        /* ILBM record */
  111.     struct Screen *ad_Screen;    /* Display screen */
  112.     UBYTE ad_Tmp[512];        /* Temporary work space */
  113.     UBYTE ad_Name[512];        /* Output name */
  114.     LONG ad_Mode;        /* Output mode */
  115.  
  116.     /* These are fields that are saved as preference items */
  117.  
  118.     UBYTE ad_Struct[32];    /* Structure name */
  119.     ULONG ad_Unit;        /* Default clipboard unit */
  120.     BOOL ad_SaveIcons;        /* Save icons? */
  121.     WORD ad_LeftEdge;        /* File requester positioning */
  122.     WORD ad_TopEdge;
  123.     WORD ad_Width;
  124.     WORD ad_Height;
  125. };
  126.  
  127. /* Application specific data */
  128. #define    IMAGE    0
  129. #define    SPRITE    1
  130. #define    ICON    2
  131.  
  132. /* Each public function gets a numeric ID assigned to it.  You must
  133.  * assign an ID to each one of your functions.  Look at appshell.h for
  134.  * standard function ID's for things like New, Open, Cut, Copy, Paste,
  135.  * Quit, etc... */
  136. enum
  137. {
  138.     DUMMYID = APSH_USER_ID,
  139.     CInitID,
  140.     CExitID,
  141.     OpenMainID,
  142.     OpenAboutID,
  143.     SetNameID,
  144.     SetModeID,
  145.     DisplayID,
  146.     ClipChangeID,
  147.     SaveSettingsID,
  148.     LAST_ID
  149. };
  150.  
  151. /* These are the function prototypes for all the application implemented
  152.  * functions used in this example.  You must prototype all the functions
  153.  * that your application is going use in the function table. */
  154. VOID CInitFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
  155. VOID CExitFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
  156. VOID OpenFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
  157. VOID SaveAsFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
  158. VOID AboutFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
  159. VOID QuitFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
  160. VOID CutFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
  161. VOID CopyFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
  162. VOID PasteFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
  163. VOID EraseFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
  164. VOID OpenMainFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
  165. VOID OpenAboutFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
  166. VOID DropIconFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
  167. VOID SetNameFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
  168. VOID SetModeFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
  169. VOID DisplayFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
  170. VOID ClipChangeFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
  171. VOID SaveSettingsFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
  172.  
  173. /* These are function prototypes that aren't going in the function
  174.  * table. */
  175. ILBM *ReadILBM (BPTR drawer, STRPTR name, struct TagItem * attrs);
  176. ILBM *GetILBM (struct IFFHandle * iff);
  177. BOOL PutILBM (struct IFFHandle * iff, ILBM * ilbm);
  178. VOID FreeILBM (ILBM * ilbm);
  179. struct PointerPref *MakePointer (ILBM * ilbm);
  180. VOID FreePointer (struct PointerPref * pp);
  181.  
  182. /* The AppShell will convert this array into function table entries and will
  183.  * add them to the function table list.  Using the APSHF_PRIVATE flag, we are
  184.  * able to have functions that can't be triggered by the user.  This
  185.  * also defines the commands that are available through ARexx.  Note that
  186.  * the command parser is case-INSENSITIVE, but for readability, your
  187.  * entries in this table should follow standard capitalization rules. */
  188. struct Funcs FTable[] =
  189. {
  190.     {"Clear", EraseFunc, ClearID, ",", 0L, NULL,},
  191.     {"Open", OpenFunc, OpenID, "FILENAME,FORCE/S", 2L, NULL,},
  192.     {"SaveAs", SaveAsFunc, SaveAsID, "FILENAME", 1L, NULL,},
  193.     {"About", AboutFunc, AboutID, ",", 0L, NULL,},
  194.     {"Quit", QuitFunc, QuitID, "FORCE/S", 1L, NULL,},
  195.     {"Cut", CutFunc, CutID, ",", 0L, NULL,},
  196.     {"Copy", CopyFunc, CopyID, ",", 0L, NULL,},
  197.     {"Paste", PasteFunc, PasteID, ",", 0L, NULL,},
  198.     {"Erase", EraseFunc, EraseID, ",", 0L, NULL,},
  199.     {"OpenMain", OpenMainFunc, OpenMainID, NULL, NULL, APSHF_PRIVATE,},
  200.     {"OpenAbout", OpenAboutFunc, OpenAboutID, NULL, NULL, APSHF_PRIVATE,},
  201.     {"CInit", CInitFunc, CInitID, NULL, NULL, APSHF_PRIVATE,},
  202.     {"CExit", CExitFunc, CExitID, NULL, NULL, APSHF_PRIVATE,},
  203.     {"DropIcon", DropIconFunc, DropIconID, NULL, NULL, APSHF_PRIVATE,},
  204.     {"SetName", SetNameFunc, SetNameID, "NAME", 1L, NULL,},
  205.     {"SetMode", SetModeFunc, SetModeID, "IMAGE/S,SPRITE/S,ICON/S", 3L, NULL,},
  206.     {"Display", DisplayFunc, DisplayID, "OFF/S", 1L, NULL,},
  207.     {"ClipChange", ClipChangeFunc, ClipChangeID, NULL, NULL, APSHF_PRIVATE,},
  208.     {"SaveSettings", SaveSettingsFunc, SaveSettingsID, ",", 0L, NULL,},
  209.  
  210.     {NULL, NO_FUNCTION,}    /* end of array */
  211. };
  212.  
  213. /*
  214.  * All text used in the application must be defined in a text array.  Then
  215.  * referred to by numeric ID.
  216.  */
  217. STRPTR app_deftext[] =
  218. {
  219.  /* Main window labels */
  220.     "<unassigned>",        /* 0 */
  221.     "ILBMer",            /* 1 */
  222.     "Graphic",            /* 2 */
  223.     "Output:",            /* 3 */
  224.     "_Label:",            /* 4 */
  225.     APPNAME,            /* 5 */
  226.     APPVERS,            /* 6 */
  227.     APPCOPY,            /* 7 */
  228.     APPAUTH,            /* 8 */
  229.     "9",            /* 9 */
  230.     "10",            /* 10 */
  231.     "11",            /* 11 */
  232.  
  233.  /* Main window menus */
  234.     "WINDOW MAIN",        /* 12 */
  235.     " TITLE PROJECT  LABEL Project",
  236.     "  ITEM OPEN     LABEL \"Open ILBM...\"     KEY O CMD Open",
  237.     "  ITEM DISPLAY  LABEL Display              KEY D CMD Display",
  238.     "  ITEM SAVEAS   LABEL \"Save...\"          KEY S CMD SaveAs",
  239.     "  ITEM ABOUT    LABEL \"About...\"               CMD About",
  240.     "  ITEM QUIT     LABEL Quit                 KEY Q CMD Quit",
  241.  
  242.     " TITLE EDIT     LABEL Edit",
  243.     "  ITEM CUT      LABEL Cut            KEY X CMD Cut",
  244.     "  ITEM COPY     LABEL Copy                 KEY C CMD Copy",
  245.     "  ITEM PASTE    LABEL Paste                KEY V CMD Paste",
  246.     "  ITEM ERASE    LABEL Erase                KEY E CMD Erase",
  247.  
  248.     " TITLE EXTRAS   LABEL Extras",
  249.     "  ITEM CMDSHELL LABEL \"Command Shell...\" KEY . CMD CmdShell",
  250.  
  251.     " TITLE PREFS    LABEL Preferences",
  252.     "  ITEM SNAPSHOT LABEL \"Save Settings\"          CMD SaveSettings",
  253.  
  254.     "   END",
  255.  
  256.  /* About window labels */
  257.     "About ILBMer",        /* 29 */
  258.     "_Continue",        /* 30 */
  259.  
  260.     "Couldn't read brush",
  261. #define    IERR_CANT_LOAD_BRUSH    31
  262.  
  263.     "Couldn't write brush",
  264. #define    IERR_CANT_WRITE_BRUSH    32
  265.  
  266.     "No brush loaded",
  267. #define    IERR_NO_BRUSH        33
  268.  
  269.     "Couldn't open clipboard.device",
  270. #define    IERR_NO_CLIPBOARD    34
  271.  
  272.     "Requires a name",
  273. #define    IERR_NO_NAME        35
  274.  
  275.     "Couldn't create %s",
  276. #define    IERR_CANT_CREATE    36
  277.  
  278.     "Aborted by user",
  279. #define    IERR_USER_ABORT        37
  280.  
  281.     "Monitor not available",
  282. #define    IERR_NOMONITOR        38
  283.  
  284.     "New chipset not available",
  285. #define    IERR_NOCHIPS        39
  286.  
  287.     "Not enough memory",
  288. #define    IERR_NOMEM        40
  289.  
  290.     "Not enough chip memory",
  291. #define    IERR_NOCHIPMEM        41
  292.  
  293.     "Public screen already open",
  294. #define    IERR_PUBNOTUNIQUE    42
  295.  
  296.     "Display mode ID is unknown",
  297. #define    IERR_UNKNOWNMODE    43
  298.  
  299.     "Unknown OpenScreen error",
  300. #define    IERR_OPENSCREEN        44
  301.     NULL
  302. };
  303.  
  304. /* If you need special tags for a window, then attach them to the
  305.  * window object, OBJ_Window. */
  306. struct TagItem win_tags[] =
  307. {
  308.     {WA_SizeGadget, TRUE},
  309.     {WA_MenuHelp, TRUE},
  310.     {WA_MinWidth, 200},
  311.     {WA_MinHeight, 90},
  312.     {WA_InnerWidth, 200},
  313.     {WA_InnerHeight, 90},
  314.     {TAG_DONE,},
  315. };
  316.  
  317. /* The following four tag arrays are GadTool tags for Window Environment
  318.  * objects. */
  319. STRPTR output_data[] =
  320. {
  321.     "C Image",
  322.     "C Sprite",
  323.     "Icon",
  324.     NULL
  325. };
  326.  
  327. STRPTR output2_data[] =
  328. {
  329.     "Image",
  330.     NULL
  331. };
  332.  
  333. struct TagItem output_tags[] =
  334. {
  335.     {GTCY_Labels, (LONG) output_data},
  336.     {TAG_DONE,}
  337. };
  338.  
  339. struct TagItem name_tags[] =
  340. {
  341.     {GTST_MaxChars, 30L},
  342.     {TAG_DONE,},
  343. };
  344.  
  345. /* These are the objects that are going to be within our main window.
  346.  * Note that the window itself is an object, and receives the SAME name
  347.  * as in the WindowEnvironment tag list, APSH_NameTag. */
  348. struct Object objects[] =
  349. {
  350.     {&objects[1], 0, 0, OBJ_Window, NULL, NULL, NULL, "Main", 1L,
  351.      {0, 0, 240, 75}, win_tags,},
  352.  
  353.     {&objects[2], 0, 0, OBJ_DblBevelOut, NULL, APSH_OBJF_DRAGGABLE, NULL, "Display", 2L,
  354.      {8, 4, -8, -30},},
  355.  
  356.     {&objects[3], 0, 0, OBJ_String, SetNameID, NULL, NULL, "Name", 4L,
  357.      {70, -26, 101, 16}, name_tags,},
  358.  
  359.     {NULL, 0, 0, OBJ_Cycle, SetModeID, NULL, NULL, "Mode", 3L,
  360.      {70, -8, 101, 16}, output_tags,},
  361. };
  362.  
  363. /* This is a Window Environment tag list.  It describes a window. */
  364. struct TagItem mainenv[] =
  365. {
  366.     {APSH_NameTag, (ULONG) "Main"},
  367.     {APSH_Objects, (ULONG) objects},
  368.     {APSH_TTMenu, 12L},
  369.     {APSH_WinAOpen, OpenMainID},
  370.     {APSH_RefreshData, OpenMainID},
  371.     {APSH_CloseWindow, QuitID},
  372.     {TAG_DONE,}
  373. };
  374.  
  375. struct TagItem icon_tags[] =
  376. {
  377.     {CGTA_MaxWidth, 80},
  378.     {CGTA_MaxHeight, 40},
  379.     {CGTA_LabelInfo, LABEL_CENTER},
  380.     {CGTA_FrameInfo, FRAME_CENTER},
  381.     {TAG_DONE,},
  382. };
  383.  
  384. struct TagItem td_tags[] =
  385. {
  386.     {APSH_GTFlags, PLACETEXT_IN},
  387.     {TAG_DONE,},
  388. };
  389.  
  390. /* This is the object array for the About window. */
  391. struct Object about[] =
  392. {
  393.     {&about[1], 0, 0, OBJ_Window, NULL, NULL, NULL, "About", 29L,
  394.      {1, 1, 0, 0},},
  395.  
  396.     {&about[2], 0, 0, OBJ_Display, NULL, NULL, NULL, "Icon", 0L,
  397.      {8, 4, 90, 44}, icon_tags,},
  398.  
  399.  /* Using the Label as the contents... */
  400.     {&about[3], 0, 0, OBJ_Text, NULL, NULL, NULL, "Name", 5L,
  401.      {116, 4, 350, 10}, td_tags,},
  402.  
  403.     {&about[4], 0, 0, OBJ_Text, NULL, NULL, NULL, "Copyright", 6L,
  404.      {116, 14, 350, 10}, td_tags,},
  405.  
  406.     {&about[5], 0, 0, OBJ_Text, NULL, NULL, NULL, "Version", 7L,
  407.      {116, 24, 350, 10}, td_tags,},
  408.  
  409.     {&about[6], 0, 0, OBJ_Text, NULL, NULL, NULL, "Author", 8L,
  410.      {116, 34, 350, 10}, td_tags,},
  411.  
  412.   {NULL, 0, 0, OBJ_Button, NULL, APSH_OBJF_CLOSEWINDOW, NULL, "Continue", 30L,
  413.    {-94, 46, 80, 12},},
  414. };
  415.  
  416. /* This is the Window Environment tag array for the About window. */
  417. struct TagItem aboutenv[] =
  418. {
  419.     {APSH_NameTag, (ULONG) "About"},    /* name to give to window */
  420.     {APSH_Objects, (ULONG) about},    /* object list */
  421.     {APSH_WinAOpen, OpenAboutID},
  422.     {TAG_DONE,}
  423. };
  424.  
  425. /* Define all the libraries that your application needs.  Note that
  426.  * extern libraries are defined in the link files. */
  427. extern ULONG SysBase, AppShellBase, DOSBase;
  428. struct Library *AslBase;
  429. struct Library *GadToolsBase;
  430. struct Library *GfxBase;
  431. struct Library *IconBase;
  432. struct Library *UtilityBase;
  433. struct Library *LayersBase;
  434. struct Library *AppObjectsBase;
  435. struct Library *IFFParseBase;
  436. struct IntuitionBase *IntuitionBase;
  437.  
  438. /* This tag array is used to open and close the shared system libraries
  439.  * needed by our application. */
  440. struct TagItem Our_Libs[] =
  441. {
  442.     {APSH_LibVersion, 36L},
  443.     {APSH_LibStatus, APSH_REQUIRED},
  444.     {APSH_ASL, (ULONG) & AslBase},
  445.     {APSH_GadTools, (ULONG) & GadToolsBase},
  446.     {APSH_Gfx, (ULONG) & GfxBase},
  447.     {APSH_Icon, (ULONG) & IconBase},
  448.     {APSH_Intuition, (ULONG) & IntuitionBase},
  449.     {APSH_Utility, (ULONG) & UtilityBase},
  450.     {APSH_Layers, (ULONG) & LayersBase},
  451.     {APSH_IFF, (ULONG) & IFFParseBase},
  452.     {APSH_LibName, (ULONG) "appobjects.library"},
  453.     {APSH_LibBase, (ULONG) & AppObjectsBase},
  454.     {TAG_DONE,}
  455. };
  456.  
  457. /* These tags describe the Intuition user interface. */
  458. struct TagItem Handle_IDCMP[] =
  459. {
  460.     {APSH_Rating, APSH_REQUIRED},
  461.     {TAG_DONE,}
  462. };
  463.  
  464. struct TagItem appwinenv[] =
  465. {
  466.     {APSH_NameTag, (ULONG) "Main"},    /* Window to make into AppWindow */
  467.     {APSH_AppDDrop, DropIconID},/* function after drop */
  468.     {APSH_CmdFlags, APSH_WBF_NOLIST},    /* Don't add the icons to any list */
  469.     {TAG_DONE,}
  470. };
  471.  
  472. /* These tags describe the Workbench user interface. */
  473. struct TagItem Handle_WB[] =
  474. {
  475.     {APSH_AppWindowEnv, (ULONG) appwinenv},
  476.     {APSH_Rating, APSH_OPTIONAL},
  477.     {TAG_DONE,}
  478. };
  479.  
  480. /* These tags describe the Simple IPC user interface. */
  481. struct TagItem Handle_SIPC[] =
  482. {
  483.     {APSH_Rating, APSH_REQUIRED},
  484.     {TAG_DONE,}
  485. };
  486.  
  487. /* These tags are used for the Asynchronous process message handler. */
  488. struct TagItem Handle_Tool[] =
  489. {
  490.     {APSH_Status, APSHP_INACTIVE},
  491.     {APSH_Rating, APSH_REQUIRED},
  492.     {TAG_DONE,}
  493. };
  494.  
  495. /* These tags describe the ARexx user interface.  The default macro file
  496.  * extension is build. */
  497. struct TagItem Handle_AREXX[] =
  498. {
  499.     {APSH_Extens, (ULONG) "ilbmer"},
  500.     {APSH_Rating, APSH_OPTIONAL},
  501.     {TAG_DONE,}
  502. };
  503.  
  504. /* These tags describe the Command Shell user interface. */
  505. struct TagItem Handle_DOS[] =
  506. {
  507.     {APSH_Status, APSHP_INACTIVE},
  508.     {APSH_Rating, APSH_OPTIONAL},
  509.     {TAG_DONE,}
  510. };
  511.  
  512. /* This is the Application Description tag list.  It is used to describe our
  513.  * application's multiple user interfaces. */
  514. struct TagItem Our_App[] =
  515. {
  516.     {APSH_BaseName, (ULONG) APPBASE},
  517.     {APSH_AppName, (ULONG) APPNAME},
  518.     {APSH_AppVersion, (ULONG) APPVERS},
  519.     {APSH_AppCopyright, (ULONG) APPCOPY},
  520.     {APSH_AppAuthor, (ULONG) APPAUTH},
  521.     {APSH_UserDataSize, sizeof (struct AppData)},
  522.     {APSH_FuncTable, (ULONG) FTable},
  523.     {APSH_DefText, (ULONG) app_deftext},
  524.     {APSH_OpenLibraries, (ULONG) Our_Libs},
  525.     {APSH_AddSIPC_UI, (ULONG) Handle_SIPC},
  526.     {APSH_AddTool_UI, (ULONG) Handle_Tool},
  527.     {APSH_AddARexx_UI, (ULONG) Handle_AREXX},
  528.     {APSH_AddIntui_UI, (ULONG) Handle_IDCMP},
  529.     {APSH_AddCmdShell_UI, (ULONG) Handle_DOS},
  530.     {APSH_AddWB_UI, (ULONG) Handle_WB},
  531.     {APSH_AppInit, CInitID},
  532.     {APSH_AppExit, CExitID},
  533.     {APSH_SIG_E, ClipChangeID},
  534.     {TAG_DONE,}
  535. };
  536.  
  537. /* handle messages between function handlers */
  538. BOOL HandlerFunc (struct AppInfo * ai, ULONG tags,...)
  539. {
  540.     return (HandlerFuncA (ai, (struct TagItem *) & tags));
  541. }
  542.  
  543. /* get handler data */
  544. APTR HandlerData (struct AppInfo * ai, ULONG tags,...)
  545. {
  546.     return (HandlerDataA (ai, (struct TagItem *) & tags));
  547. }
  548.  
  549. LONG
  550. fprint (BPTR fh, UBYTE * format, LONG data,...)
  551. {
  552.     LONG VFPrintf (BPTR fh, UBYTE * format, LONG * argarray);
  553.  
  554.     return (VFPrintf (fh, format, (ULONG *) & data));
  555. }
  556.  
  557. BOOL CopyImage (struct Image * src, struct Image * dst)
  558. {
  559.     BOOL retval = FALSE;
  560.  
  561.     if (src && dst)
  562.     {
  563.     int msize;
  564.  
  565.     /* Copy the Image structure */
  566.     CopyMem (src, dst, sizeof (struct Image));
  567.  
  568.     /* Don't go pointing off into nowhere land */
  569.     dst->NextImage = NULL;
  570.  
  571.     /* Compute the size of the image data needed */
  572.     msize = RASSIZE (src->Width, src->Height) * src->Depth;
  573.  
  574.     /* Allocate the image data */
  575.     if (dst->ImageData = (USHORT *)
  576.         AllocVec (msize, MEMF_CLEAR | MEMF_CHIP))
  577.     {
  578.         /* Copy image data */
  579.         CopyMem (src->ImageData, dst->ImageData, msize);
  580.  
  581.         /* Indicate success */
  582.         retval = TRUE;
  583.     }
  584.     }
  585.  
  586.     return (retval);
  587. }
  588.  
  589. VOID FreeImage (struct Image * im)
  590. {
  591.  
  592.     if (im && im->ImageData)
  593.     {
  594.     FreeVec (im->ImageData);
  595.     im->ImageData = NULL;
  596.     }
  597. }
  598.  
  599. /* Get the file requester set up properly.  Returns 0 if no file node
  600.  * present, returns > 0 if there is a file node.  */
  601. LONG FixFileAndPath (struct FileRequester *rf, STRPTR name)
  602. {
  603.     LONG count = 0L;
  604.  
  605.     if (rf)
  606.     {
  607.     if (name)
  608.     {
  609.         stcgfp (rf->rf_Dir, name);
  610.         count = (LONG) stcgfn (rf->rf_File, name);
  611.     }
  612.     else
  613.     {
  614.         WORD dlen = (strlen (rf->rf_Dir) - 1);
  615.  
  616.         if ((dlen > 0) && (rf->rf_Dir[dlen] == '/'))
  617.         {
  618.         rf->rf_Dir[dlen] = 0;
  619.         }
  620.     }
  621.     }
  622.  
  623.     return (count);
  624. }
  625.  
  626. VOID
  627. ImageToC (BPTR fh, STRPTR name, struct Image * i)
  628. {
  629.     int w, h, d, c, t, cp;
  630.     register int j, k;
  631.     USHORT *data;
  632.  
  633.     /* Image data portion */
  634.     fprint (fh, "UWORD chip %s_idata[] =\n{\n", (LONG) name);
  635.     w = i->Width;
  636.     h = i->Height;
  637.     d = i->Depth;
  638.     c = ((w + 15) / 16) * h;
  639.     cp = 0;
  640.     data = i->ImageData;
  641.     for (k = 0; k < d; k++)
  642.     {
  643.     if (k > 0)
  644.         fprint (fh, "\n", NULL);
  645.     fprint (fh, "/* Plane %ld */\n    ", (LONG) k);
  646.     t = 0;
  647.     for (j = 0; j < c; j++)
  648.     {
  649.         if (t > 7)
  650.         {
  651.         fprint (fh, "\n    ", NULL);
  652.         t = 0;
  653.         }
  654.         t++;
  655.         fprint (fh, "0x%04lx,", (LONG) data[cp++]);
  656.     }
  657.     }
  658.     fprint (fh, "\n};\n\n", NULL);
  659.  
  660.     /* Image structure portion */
  661.     fprint (fh, "struct Image %s_data =\n{\n", (LONG) name);
  662.     fprint (fh, "    %ld, %ld,            /* Upper left corner */\n",
  663.         (LONG) i->LeftEdge, (LONG) i->TopEdge);
  664.     fprint (fh, "    %ld, %ld, %ld,            /* Width, Height, Depth */\n",
  665.         (LONG) w, (LONG) h, (LONG) d);
  666.     fprint (fh, "    %s_idata,        /* Image data */\n", (LONG) name);
  667.     fprint (fh, "    0x%04lx, 0x%04lx,        /* PlanePick, PlaneOnOff */\n",
  668.         (LONG) i->PlanePick, (LONG) i->PlaneOnOff);
  669.     fprint (fh, "    NULL            /* Next image */\n", NULL);
  670.     fprint (fh, "};\n\n", NULL);
  671. }
  672.  
  673. VOID SpriteToC (BPTR fh, STRPTR name, struct PointerPref * pp)
  674. {
  675.     WORD i, j, num;
  676.     WORD gw, gh, gx, gy;
  677.  
  678.     /* Get the sizes */
  679.     gw = pp->pp_Width;
  680.     gh = pp->pp_Height;
  681.     gx = pp->pp_XOffset;
  682.     gy = pp->pp_YOffset;
  683.     num = (gh * 2) + 4;
  684.  
  685.     /* Pointer header */
  686.     fprint (fh, "UWORD chip %s_sdata[] =\n{\n", (LONG) name);
  687.  
  688.     /* Header */
  689.     fprint (fh, "    0x0000, 0x0000,\n\n", NULL);
  690.  
  691.     /* Body */
  692.     for (i = 2; i < ((gh * 2) + 2); i++)
  693.     {
  694.     j = i + 1;
  695.  
  696.     fprint (fh, "    0x%04lx, 0x%04lx,\n",
  697.         (LONG) pp->pp_PData[i], (LONG) pp->pp_PData[j]);
  698.     i++;
  699.     }
  700.  
  701.     /* Tail */
  702.     fprint (fh, "\n    0x0000, 0x0000\n};\n\n", NULL);
  703.  
  704.     /* Set?Pointer function */
  705.     fprint (fh, "VOID Set%sPointer (struct Window *win)\n{\n", (LONG) name);
  706.     fprint (fh, "    SetPointer (win, %s_sdata, %ld, 16, %ld, %ld);\n",
  707.         (LONG) name, (LONG) gh, (LONG) gx, (LONG) gy);
  708.  
  709.     fprint (fh, "}\n", NULL);
  710. }
  711.  
  712. UWORD
  713. Pick (UWORD depth)
  714. {
  715.     UWORD ret;
  716.  
  717.     switch (depth)
  718.     {
  719.     case 1:
  720.         ret = 1;
  721.         break;
  722.  
  723.     case 2:
  724.         ret = 3;
  725.         break;
  726.  
  727.     case 3:
  728.         ret = 7;
  729.         break;
  730.  
  731.     case 4:
  732.         ret = 15;
  733.         break;
  734.  
  735.     case 5:
  736.         ret = 31;
  737.         break;
  738.  
  739.     case 6:
  740.         ret = 31;
  741.         break;
  742.  
  743.     default:
  744.         ret = 0;
  745.         break;
  746.     }
  747.  
  748.     return (ret);
  749. }
  750.  
  751. BOOL
  752. MakeImage (struct Image * im, ILBM * ir)
  753. {
  754.     BOOL retval = FALSE;
  755.  
  756.     if (im && ir)
  757.     {
  758.     struct BitMap *bm = &(ir->ir_BMap);
  759.     UWORD *wp, *data;
  760.     ULONG msize;
  761.     int p, j, nb, nwords, total = 0;
  762.     int w, h, d;
  763.  
  764.     w = ir->ir_Width;
  765.     h = ir->ir_Height;
  766.     d = ir->ir_Depth;
  767.  
  768.     total = 0;
  769.     nwords = (bm->BytesPerRow / 2) * bm->Rows;
  770.     msize = (ULONG) ((bm->BytesPerRow * bm->Rows) * (bm->Depth) / 2) * (sizeof (USHORT));
  771.  
  772.     if (data = (UWORD *) AllocVec (msize, MEMF_CLEAR | MEMF_CHIP))
  773.     {
  774.         for (p = 0; p < bm->Depth; ++p)
  775.         {
  776.         wp = (UWORD *) bm->Planes[p];
  777.  
  778.         for (j = 0; j < bm->Rows; j++, wp += (bm->BytesPerRow >> 1))
  779.         {
  780.             for (nb = 0; nb < (bm->BytesPerRow) >> 1; nb++)
  781.             {
  782.             data[total++] = *(wp + nb);
  783.             }
  784.         }
  785.         }
  786.  
  787.         /* Fill out the image structure */
  788.         im->LeftEdge = 0;
  789.         im->TopEdge = 0;
  790.         im->Width = w;
  791.         im->Height = h;
  792.         im->Depth = bm->Depth;
  793.         im->PlanePick = Pick (bm->Depth);
  794.         im->PlaneOnOff = 1;
  795.         im->ImageData = data;
  796.  
  797.         /* Success! */
  798.         retval = TRUE;
  799.     }
  800.     }
  801.     return (retval);
  802. }
  803.  
  804. VOID FreeGraphic (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  805. {
  806.     struct AppData *ad = (struct AppData *) ai->ai_UserData;
  807.  
  808.     if (ad)
  809.     {
  810.     if (ad->ad_Screen)
  811.     {
  812.         CloseScreen (ad->ad_Screen);
  813.         ad->ad_Screen = NULL;
  814.     }
  815.  
  816.     /* Free the image structure */
  817.     FreeImage (&(ad->ad_Image));
  818.  
  819.     /* Free the pointer */
  820.     if (ad->ad_Ptr)
  821.     {
  822.         FreePointer (ad->ad_Ptr);
  823.         ad->ad_Ptr = NULL;
  824.     }
  825.     /* Free the ILBM record */
  826.     if (ad->ad_IR)
  827.     {
  828.         FreeILBM (ad->ad_IR);
  829.         ad->ad_IR = NULL;
  830.     }
  831.     }
  832. }
  833.  
  834. /* This function gets called after all the user interfaces have been
  835.  * initialized, and before the AppShell enters the main event processing
  836.  * loop.  It is specified by the APSH_AppInit tag in the Application
  837.  * Description tag array.  Note that the AppData structure has been
  838.  * allocated for us, due to the APSH_UserDataSize tag. */
  839.  
  840. VOID
  841. CInitFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  842. {
  843.     struct AppData *ad = (struct AppData *) ai->ai_UserData;
  844.     extern struct TagItem mainenv[];
  845.     struct DiskObject *dob;
  846.     WORD i;
  847.  
  848.     /* Allocate the file requesters */
  849.     for (i = 0; i < FR_MAX; i++)
  850.     {
  851.     ad->ad_FR[i] = AllocAslRequest (ASL_FileRequest, NULL);
  852.     }
  853.  
  854.     /* Unset the file requester positioning */
  855.     ad->ad_Width = (-1);
  856.  
  857.     /* Do we want to save icons? */
  858.     ad->ad_SaveIcons = TRUE;
  859.  
  860.     /* Do we have a tool icon? */
  861.     if (dob = ai->ai_ProgDO)
  862.     {
  863.     LONG hold;
  864.     UBYTE *tmp;
  865.  
  866.     /* Get the clipboard unit to use */
  867.     if (tmp = FindToolType (dob->do_ToolTypes, "UNIT"))
  868.     {
  869.         if (StrToLong (tmp, &hold) > 0L)
  870.         {
  871.         ad->ad_Unit = hold;
  872.         }
  873.     }
  874.  
  875.     /* Get the file requester topedge */
  876.     if (tmp = FindToolType (dob->do_ToolTypes, "FRTOPEDGE"))
  877.     {
  878.         if (StrToLong (tmp, &hold) > 0L)
  879.         {
  880.         ad->ad_TopEdge = (WORD) hold;
  881.         }
  882.     }
  883.  
  884.     /* Get the file requester leftedge */
  885.     if (tmp = FindToolType (dob->do_ToolTypes, "FRLEFTEDGE"))
  886.     {
  887.         if (StrToLong (tmp, &hold) > 0L)
  888.         {
  889.         ad->ad_LeftEdge = (WORD) hold;
  890.         }
  891.     }
  892.  
  893.     /* Get the file requester width */
  894.     if (tmp = FindToolType (dob->do_ToolTypes, "FRWIDTH"))
  895.     {
  896.         if (StrToLong (tmp, &hold) > 0L)
  897.         {
  898.         ad->ad_Width = (WORD) hold;
  899.         }
  900.     }
  901.  
  902.     /* Get the file requester height */
  903.     if (tmp = FindToolType (dob->do_ToolTypes, "FRHEIGHT"))
  904.     {
  905.         if (StrToLong (tmp, &hold) > 0L)
  906.         {
  907.         ad->ad_Height = (WORD) hold;
  908.         }
  909.     }
  910.  
  911.     /* Do we have a default brush drawer? */
  912.     if (tmp = FindToolType (dob->do_ToolTypes, "ILBMDRAWER"))
  913.     {
  914.         strcpy (ad->ad_FR[FR_ILBM]->rf_Dir, tmp);
  915.     }
  916.  
  917.     /* Do we have a default source drawer? */
  918.     if (tmp = FindToolType (dob->do_ToolTypes, "SRCDRAWER"))
  919.     {
  920.         strcpy (ad->ad_FR[FR_C]->rf_Dir, tmp);
  921.     }
  922.  
  923.     /* Do we have a default structure label? */
  924.     if (tmp = FindToolType (dob->do_ToolTypes, "LABEL"))
  925.     {
  926.         strncpy (ad->ad_Struct, tmp, 31);
  927.     }
  928.  
  929.     /* Save icons? */
  930.     if (tmp = FindToolType (dob->do_ToolTypes, "NOICONS"))
  931.     {
  932.         ad->ad_SaveIcons = FALSE;
  933.     }
  934.     }
  935.  
  936.     /* Allocate clipboard manager */
  937.     if (ad->ad_CM = AllocClip ())
  938.     {
  939.     /* Start the change hook */
  940.     StartClipChangeHook (ad->ad_CM, ad->ad_Unit);
  941.     }
  942.  
  943.     /* open the Main window */
  944.     HandlerFunc (ai,
  945.          APSH_Handler, "IDCMP",
  946.          APSH_Command, APSH_MH_OPEN,
  947.          APSH_WindowEnv, (ULONG) mainenv,
  948.          TAG_DONE);
  949.  
  950.     /* Initialize the clipboard stuff */
  951.     ClipChangeFunc (h, ai, af);
  952.  
  953.     /* Set the function attributes */
  954.     PerfFunc (ai, NULL, "disable display saveas copy setname setmode savesettings", NULL);
  955. }
  956.  
  957. /* This function gets called after the main event processing loop exits,
  958.  * and before deallocating all the user interfaces.  It is specified by the
  959.  * APSH_AppExit tag in the Application Description tag array.  Note that the
  960.  * AppData structure which has been allocated for us, is deallocated by
  961.  * AppShell after freeing the user interfaces. */
  962.  
  963. VOID
  964. CExitFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  965. {
  966.     struct AppData *ad = (struct AppData *) ai->ai_UserData;
  967.     WORD i;
  968.  
  969.     if (ad)
  970.     {
  971.     /* Free any existing graphics */
  972.     FreeGraphic (h, ai, af);
  973.  
  974.     /* Free the clipboard manager */
  975.     if (ad->ad_CM)
  976.     {
  977.         FreeClip (ad->ad_CM);
  978.     }
  979.  
  980.     /* Free the file requesters */
  981.     for (i = 0; i < FR_MAX; i++)
  982.     {
  983.         /* Do we have a file requester? */
  984.         if (ad->ad_FR[i])
  985.         {
  986.         /* Free the file requester */
  987.         FreeFileRequest (ad->ad_FR[i]);
  988.         ad->ad_FR[i] = NULL;
  989.         }
  990.     }
  991.     }
  992. }
  993.  
  994. /* This function is called every time the Main window is opened.  It
  995.  * was specified by using the APSH_WinAOpen tag in the Main Window
  996.  * Environemt tag array.  I'm also 'cheating' and calling it everytime
  997.  * I want to refresh the window and graphics. */
  998.  
  999. VOID
  1000. OpenMainFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  1001. {
  1002.     struct AppData *ad = (struct AppData *) ai->ai_UserData;
  1003.     struct Image *im = &(ad->ad_Image);
  1004.     struct Window *win;
  1005.     struct Gadget *gad;
  1006.  
  1007.     /* Do we have an image? */
  1008.     if (im->ImageData)
  1009.     {
  1010.     /* Set the function attributes */
  1011.     PerfFunc (ai, NULL, "enable force display saveas cut copy erase setname setmode", NULL);
  1012.     }
  1013.     /* No image */
  1014.     else
  1015.     {
  1016.     /* Set the function attributes */
  1017.     PerfFunc (ai, NULL, "disable display saveas cut copy erase setname setmode", NULL);
  1018.     }
  1019.  
  1020.     /* Update the imagry */
  1021.     if (APSHGetGadgetInfo (ai, "Main", "Display",
  1022.                (ULONG *) & win, (ULONG *) & gad))
  1023.     {
  1024.     /* Do we have an image? */
  1025.     if (im->ImageData)
  1026.     {
  1027.         /* Let the gadget know that there is an image */
  1028.         SetGadgetAttrs (gad, win, NULL, GA_LABELIMAGE, im, TAG_DONE);
  1029.     }
  1030.     /* No image */
  1031.     else
  1032.     {
  1033.         /* Let the gadget know that there isn't an image */
  1034.         SetGadgetAttrs (gad, win, NULL, GA_LABELIMAGE, NULL, TAG_DONE);
  1035.     }
  1036.     }
  1037.  
  1038.     /* Update the structure name */
  1039.     if (APSHGetGadgetInfo (ai, "Main", "Name",
  1040.                (ULONG *) & win, (ULONG *) & gad))
  1041.     {
  1042.     /* update the string gadget if there is one */
  1043.     GT_SetGadgetAttrs (gad, win, NULL,
  1044.                GTST_String, ad->ad_Struct,
  1045.                TAG_DONE);
  1046.     }
  1047.  
  1048.     /* Update the mode gadget */
  1049.     if (APSHGetGadgetInfo (ai, "Main", "Mode", (ULONG *) & win, (ULONG *) & gad))
  1050.     {
  1051.     /* Update the string gadget */
  1052.     GT_SetGadgetAttrs (gad, win, NULL, GTCY_Active, ad->ad_Mode, TAG_DONE);
  1053.     }
  1054. }
  1055.  
  1056. /*
  1057.  
  1058. RequestFile
  1059. WINDOW/K,SAVE/S,PROMPT/K,PATTERN/K,FILENAME/F
  1060.  
  1061. RequestFile opens the file requester and prompts the user to select a
  1062. file.
  1063.  
  1064.     WINDOW
  1065.     Specify the name of the window to open relative to.  Defaults to
  1066.     "Main".
  1067.  
  1068.     SAVE
  1069.     Indicate the Save file requester is to be used.
  1070.  
  1071.     PROMPT
  1072.     Allows you to specify the text which appears in the title bar of the
  1073.     file requester.
  1074.  
  1075.     PATTERN
  1076.     Specifies the pattern string to include in the file requester's
  1077.     Pattern gadget.
  1078.  
  1079.     FILENAME
  1080.     Specifies the directory path to include in the file requester's
  1081.     Drawer and File gadgets.
  1082.  
  1083. The resulting filename is returned in the ARexx RESULT variable. If the
  1084. user cancels the file requester, an error is generated.
  1085.  
  1086. This command can only be used through the ARexx interface.
  1087.  
  1088.     {"RequestFile", RequestFileFunc, RequestFileID,
  1089.      "WINDOW/K,SAVE/S,PROMPT/K,PATTERN/K,FILENAME/F", 5L, NULL,},
  1090.  
  1091.  */
  1092.  
  1093. VOID
  1094. RequestFileFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  1095. {
  1096. }
  1097.  
  1098.  
  1099. VOID
  1100. OpenFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  1101. {
  1102.     struct AppData *ad = (struct AppData *) ai->ai_UserData;
  1103.     struct TagItem *attrs = af->af_Attrs;
  1104.     struct FileRequester *rf;
  1105.     struct Funcs *f;
  1106.     STRPTR name = NULL;
  1107.     BOOL cancel = FALSE;
  1108.  
  1109.     /* set the wait pointer */
  1110.     APSHSetWaitPointer (ai, NULL);
  1111.  
  1112.     /* See if we have a parsed command */
  1113.     if (f = af->af_FE)
  1114.     {
  1115.     /* See if they passed a file name */
  1116.     name = (STRPTR) f->fe_Options[0];
  1117.     }
  1118.     else
  1119.     {
  1120.     /* See if they passed a name with a tag */
  1121.     name = (STRPTR) GetTagData (APSH_NameTag, NULL, attrs);
  1122.     }
  1123.  
  1124.     /* Do we need to prompt for a name? */
  1125.     if (!(name))
  1126.     {
  1127.     /* Do we have a file requester? */
  1128.     if (rf = ad->ad_FR[FR_ILBM])
  1129.     {
  1130.         struct TagItem tg[10];
  1131.         struct Window *win = NULL;
  1132.  
  1133.         /* Get the window pointer */
  1134.         APSHGetWindowInfo (ai, "Main", (ULONG *) & win);
  1135.  
  1136.         /* Initialize the file requester position */
  1137.         if (ad->ad_Width == (-1))
  1138.         {
  1139.         ad->ad_LeftEdge = (win) ? (win->BorderLeft + 1) : 0;
  1140.         ad->ad_TopEdge = (win) ? win->BorderTop : 0;
  1141.         ad->ad_Width = 320;
  1142.         ad->ad_Height = MAX (((win) ? (win->Height - (win->BorderTop + win->BorderBottom)) : 150), 140);
  1143.         }
  1144.  
  1145.         /* Set the file requester position */
  1146.         tg[4].ti_Tag = ASL_LeftEdge;
  1147.         tg[4].ti_Data = (ULONG) (win) ? (win->LeftEdge + ad->ad_LeftEdge) : ad->ad_LeftEdge;
  1148.         tg[5].ti_Tag = ASL_TopEdge;
  1149.         tg[5].ti_Data = (ULONG) (win) ? (win->TopEdge + ad->ad_TopEdge) : ad->ad_TopEdge;
  1150.         tg[6].ti_Tag = ASL_Width;
  1151.         tg[6].ti_Data = (ULONG) ad->ad_Width;
  1152.         tg[7].ti_Tag = ASL_Height;
  1153.         tg[7].ti_Data = (ULONG) ad->ad_Height;
  1154.  
  1155.         tg[0].ti_Tag = ASL_Hail;
  1156.         tg[0].ti_Data = (ULONG) "Select File to Open";
  1157.         tg[1].ti_Tag = ASL_FuncFlags;
  1158.         tg[1].ti_Data = NULL;
  1159.         tg[2].ti_Tag = ASL_OKText;
  1160.         tg[2].ti_Data = (ULONG) "Open";
  1161.         tg[3].ti_Tag = ASL_Window;
  1162.         tg[3].ti_Data = (ULONG) win;
  1163.         tg[8].ti_Tag = ASL_Pattern;
  1164.         tg[8].ti_Data = (ULONG) "~(#?.info)";
  1165.         tg[9].ti_Tag = TAG_DONE;
  1166.  
  1167.         /* Request the name */
  1168.         if (AslRequest (rf, tg))
  1169.         {
  1170.         /* Fix the entries */
  1171.         FixFileAndPath (rf, NULL);
  1172.         strcpy (ad->ad_Tmp, rf->rf_Dir);
  1173.         AddPart (ad->ad_Tmp, rf->rf_File, 510);
  1174.  
  1175.         /* See if a name was entered */
  1176.         if (FixFileAndPath (rf, ad->ad_Tmp))
  1177.         {
  1178.             name = ad->ad_Tmp;
  1179.         }
  1180.         }
  1181.         else
  1182.         {
  1183.         /* User aborted requester */
  1184.         ai->ai_Pri_Ret = RETURN_WARN;
  1185.         ai->ai_Sec_Ret = IERR_USER_ABORT;
  1186.         ai->ai_TextRtn =
  1187.           PrepText (ai, APSH_USER_ID, IERR_USER_ABORT, NULL);
  1188.  
  1189.         /* Canceled */
  1190.         cancel = TRUE;
  1191.         }
  1192.  
  1193.         /* Remember where they moved it */
  1194.         ad->ad_LeftEdge = rf->rf_LeftEdge - ((win) ? win->LeftEdge : 0);
  1195.         ad->ad_TopEdge = rf->rf_TopEdge - ((win) ? win->TopEdge : 0);
  1196.         ad->ad_Width = rf->rf_Width;
  1197.         ad->ad_Height = rf->rf_Height;
  1198.     }
  1199.     }
  1200.  
  1201.     /* Do we have a file name */
  1202.     if (!cancel && name)
  1203.     {
  1204.     /* Free any existing graphics */
  1205.     FreeGraphic (h, ai, af);
  1206.  
  1207.     /* Update the file name */
  1208.     strcpy (ad->ad_Name, name);
  1209.  
  1210.     /* Update the file requester gadgets */
  1211.     FixFileAndPath (rf, ad->ad_Name);
  1212.  
  1213.     /* Read the ILBM record into memory */
  1214.     if (ad->ad_IR = ReadILBM (NULL, ad->ad_Name, NULL))
  1215.     {
  1216.         /* Make an Image out of the bitmap */
  1217.         MakeImage (&(ad->ad_Image), ad->ad_IR);
  1218.  
  1219.         /* Make a pointer out of the bitmap */
  1220.         ad->ad_Ptr = MakePointer (ad->ad_IR);
  1221.  
  1222.     }
  1223.     else
  1224.     {
  1225.         /* Notify user unable to load brush */
  1226.         ai->ai_Pri_Ret = RETURN_ERROR;
  1227.         ai->ai_Sec_Ret = IERR_CANT_LOAD_BRUSH;
  1228.         ai->ai_TextRtn =
  1229.           PrepText (ai, APSH_USER_ID, IERR_CANT_LOAD_BRUSH, NULL);
  1230.     }
  1231.  
  1232.     /* Refresh the display */
  1233.     OpenMainFunc (h, ai, af);
  1234.     }
  1235.     else if (!cancel)
  1236.     {
  1237.     /* No name given */
  1238.     ai->ai_Pri_Ret = RETURN_ERROR;
  1239.     ai->ai_Sec_Ret = IERR_NO_NAME;
  1240.     ai->ai_TextRtn =
  1241.       PrepText (ai, APSH_USER_ID, IERR_NO_NAME, NULL);
  1242.     }
  1243.  
  1244.     /* clear the wait pointer */
  1245.     APSHClearPointer (ai, NULL);
  1246. }
  1247.  
  1248. VOID
  1249. SaveAsFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  1250. {
  1251.     struct AppData *ad = (struct AppData *) ai->ai_UserData;
  1252.     struct TagItem *attrs = af->af_Attrs;
  1253.     struct FileRequester *rf;
  1254.     BOOL cancel = FALSE;
  1255.  
  1256.     /* set the wait pointer */
  1257.     APSHSetWaitPointer (ai, NULL);
  1258.  
  1259.     /* Do we have a window? */
  1260.     if (ad->ad_Image.ImageData)
  1261.     {
  1262.     struct Funcs *f;
  1263.     STRPTR name;
  1264.  
  1265.     /* See if we have a parsed command */
  1266.     if (f = af->af_FE)
  1267.     {
  1268.         /* See if they passed a file name */
  1269.         name = (STRPTR) f->fe_Options[0];
  1270.     }
  1271.     else
  1272.     {
  1273.         /* See if they passed a name with a tag */
  1274.         name = (STRPTR) GetTagData (APSH_NameTag, NULL, attrs);
  1275.     }
  1276.  
  1277.     /* Do we need to prompt for a name? */
  1278.     if (!(name))
  1279.     {
  1280.         /* Do we have a file requester? */
  1281.         if (rf = ad->ad_FR[FR_C])
  1282.         {
  1283.         struct TagItem tg[10];
  1284.         struct Window *win;
  1285.  
  1286.         /* Get the window pointer */
  1287.         APSHGetWindowInfo (ai, "Main", (ULONG *) & win);
  1288.  
  1289.         /* Initialize the file requester position */
  1290.         if (ad->ad_Width == (-1))
  1291.         {
  1292.             ad->ad_LeftEdge = (win) ? (win->BorderLeft + 1) : 0;
  1293.             ad->ad_TopEdge = (win) ? win->BorderTop : 0;
  1294.             ad->ad_Width = 320;
  1295.             ad->ad_Height = MAX (((win) ? (win->Height - (win->BorderTop + win->BorderBottom)) : 150), 140);
  1296.         }
  1297.  
  1298.         /* Set the file requester position */
  1299.         tg[4].ti_Tag = ASL_LeftEdge;
  1300.         tg[4].ti_Data = (ULONG) (win) ? (win->LeftEdge + ad->ad_LeftEdge) : ad->ad_LeftEdge;
  1301.         tg[5].ti_Tag = ASL_TopEdge;
  1302.         tg[5].ti_Data = (ULONG) (win) ? (win->TopEdge + ad->ad_TopEdge) : ad->ad_TopEdge;
  1303.         tg[6].ti_Tag = ASL_Width;
  1304.         tg[6].ti_Data = (ULONG) ad->ad_Width;
  1305.         tg[7].ti_Tag = ASL_Height;
  1306.         tg[7].ti_Data = (ULONG) ad->ad_Height;
  1307.  
  1308.         tg[0].ti_Tag = ASL_Hail;
  1309.         tg[0].ti_Data = (ULONG) "Select File to Save";
  1310.         tg[1].ti_Tag = ASL_FuncFlags;
  1311.         tg[1].ti_Data = FILF_SAVE;
  1312.         tg[2].ti_Tag = ASL_OKText;
  1313.         tg[2].ti_Data = (ULONG) "Save";
  1314.         tg[3].ti_Tag = ASL_Window;
  1315.         tg[3].ti_Data = (ULONG) win;
  1316.         tg[8].ti_Tag = ASL_Pattern;
  1317.         tg[8].ti_Data = (ULONG) "~(#?.info)";
  1318.         tg[9].ti_Tag = TAG_DONE;
  1319.  
  1320.         /* Request the name */
  1321.         if (AslRequest (rf, tg))
  1322.         {
  1323.             /* Fix the entries */
  1324.             FixFileAndPath (rf, NULL);
  1325.             strcpy (ad->ad_Tmp, rf->rf_Dir);
  1326.             AddPart (ad->ad_Tmp, rf->rf_File, 510);
  1327.  
  1328.             /* Did they enter a file name? */
  1329.             if (FixFileAndPath (rf, ad->ad_Tmp))
  1330.             {
  1331.             name = ad->ad_Tmp;
  1332.             }
  1333.         }
  1334.         else
  1335.         {
  1336.             /* User aborted requester */
  1337.             ai->ai_Pri_Ret = RETURN_WARN;
  1338.             ai->ai_Sec_Ret = IERR_USER_ABORT;
  1339.             ai->ai_TextRtn =
  1340.               PrepText (ai, APSH_USER_ID, IERR_USER_ABORT, NULL);
  1341.  
  1342.             /* Indicate canceled */
  1343.             cancel = TRUE;
  1344.         }
  1345.  
  1346.         /* Remember where they moved it */
  1347.         ad->ad_LeftEdge = rf->rf_LeftEdge - ((win) ? win->LeftEdge : 0);
  1348.         ad->ad_TopEdge = rf->rf_TopEdge - ((win) ? win->TopEdge : 0);
  1349.         ad->ad_Width = rf->rf_Width;
  1350.         ad->ad_Height = rf->rf_Height;
  1351.         }
  1352.     }
  1353.  
  1354.     /* Do we have a name to save to? */
  1355.     if (!cancel && name)
  1356.     {
  1357.         BPTR fh = NULL;
  1358.  
  1359.         /* Update the file requester */
  1360.         strcpy (ad->ad_Name, name);
  1361.         FixFileAndPath (rf, ad->ad_Name);
  1362.  
  1363.         /* See if we should be saving an icon */
  1364.         if (ad->ad_Mode == ICON)
  1365.         {
  1366.         struct Image *nim = &(ad->ad_Image);
  1367.         struct Image *oim1 = NULL;
  1368.         struct Image *oim2 = NULL;
  1369.         struct DiskObject *dob;
  1370.         struct Gadget *gad;
  1371.         USHORT flags;
  1372.  
  1373.         /* Get a template icon */
  1374.         if (dob = GetDefDiskObject (WBPROJECT))
  1375.         {
  1376.             /* Cache the pointer to the gadget */
  1377.             gad = &(dob->do_Gadget);
  1378.  
  1379.             /* Remember the original imagry */
  1380.             oim1 = (struct Image *) gad->GadgetRender;
  1381.             oim2 = (struct Image *) gad->SelectRender;
  1382.             flags = gad->Flags;
  1383.  
  1384.             /* Put our stuff there */
  1385.             gad->Width = nim->Width;
  1386.             gad->Height = nim->Height;
  1387.             gad->GadgetRender = (APTR) nim;
  1388.             gad->SelectRender = NULL;
  1389.             gad->Flags &= ~GFLG_GADGHIGHBITS;
  1390.             gad->Flags |= (GFLG_GADGIMAGE | GFLG_GADGHCOMP);
  1391.  
  1392.             /* Save the icon */
  1393.             PutDiskObject (ad->ad_Name, dob);
  1394.  
  1395.             /* Restore the original image */
  1396.             gad->GadgetRender = (APTR) oim1;
  1397.             gad->SelectRender = (APTR) oim2;
  1398.             gad->Flags = flags;
  1399.  
  1400.             /* Free the temporary icon */
  1401.             FreeDiskObject (dob);
  1402.         }
  1403.         }
  1404.         /* Open the output file */
  1405.         else if (fh = Open (ad->ad_Name, MODE_NEWFILE))
  1406.         {
  1407.         if (ad->ad_Mode == IMAGE)
  1408.         {
  1409.             /* Save the image as C source */
  1410.             ImageToC (fh, ad->ad_Struct, &(ad->ad_Image));
  1411.         }
  1412.         else if (ad->ad_Mode == SPRITE)
  1413.         {
  1414.             /* Save the pointer as C source */
  1415.             SpriteToC (fh, ad->ad_Struct, ad->ad_Ptr);
  1416.         }
  1417.  
  1418.         /* Close the file */
  1419.         Close (fh);
  1420.  
  1421.         /* Clear the execute file attribute */
  1422.         SetProtection (ad->ad_Name, FIBF_EXECUTE);
  1423.  
  1424.         /* Do we save icons? */
  1425.         if (ad->ad_SaveIcons)
  1426.         {
  1427.             /*
  1428.              * This is a bit silly, I just did it because I could.
  1429.              * Remember MORE uses this Env variable also.
  1430.              */
  1431.             if (GetVar ("EDITOR", ad->ad_Tmp, 510, NULL))
  1432.             {
  1433.             Listing.do_DefaultTool = ad->ad_Tmp;
  1434.             }
  1435.  
  1436.             /* Save the icon */
  1437.             PutDiskObject (ad->ad_Name, &Listing);
  1438.         }
  1439.         }
  1440.         else
  1441.         {
  1442.         /* Unable to create the new file */
  1443.         ai->ai_Pri_Ret = RETURN_ERROR;
  1444.         ai->ai_Sec_Ret = IERR_CANT_CREATE;
  1445.         ai->ai_TextRtn =
  1446.           PrepText (ai, APSH_USER_ID, IERR_CANT_CREATE, (int) ad->ad_Name);
  1447.         }
  1448.     }
  1449.     else if (!cancel)
  1450.     {
  1451.         /* No name given */
  1452.         ai->ai_Pri_Ret = RETURN_ERROR;
  1453.         ai->ai_Sec_Ret = IERR_NO_NAME;
  1454.         ai->ai_TextRtn =
  1455.           PrepText (ai, APSH_USER_ID, IERR_NO_NAME, NULL);
  1456.     }
  1457.     }
  1458.     else
  1459.     {
  1460.     /* No image loaded */
  1461.     ai->ai_Pri_Ret = RETURN_ERROR;
  1462.     ai->ai_Sec_Ret = IERR_NO_BRUSH;
  1463.     ai->ai_TextRtn =
  1464.       PrepText (ai, APSH_USER_ID, IERR_NO_BRUSH, NULL);
  1465.     }
  1466.  
  1467.     /* clear the wait pointer */
  1468.     APSHClearPointer (ai, NULL);
  1469. }
  1470.  
  1471. VOID
  1472. AboutFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  1473. {
  1474.     struct Window *win;
  1475.     struct Gadget *gad;
  1476.  
  1477.     /* open the Hotkey editor */
  1478.     HandlerFunc (ai,
  1479.          APSH_Handler, "IDCMP",
  1480.          APSH_Command, APSH_MH_OPEN,
  1481.          APSH_WindowEnv, (ULONG) aboutenv,
  1482.          TAG_DONE);
  1483.  
  1484.     /* See if we have a tool icon */
  1485.     if (ai->ai_ProgDO)
  1486.     {
  1487.     struct Image *im;
  1488.  
  1489.     im = (struct Image *) (ai->ai_ProgDO->do_Gadget.GadgetRender);
  1490.  
  1491.     /* Update the imagry */
  1492.     if (APSHGetGadgetInfo (ai, "About", "Icon",
  1493.                    (ULONG *) & win, (ULONG *) & gad))
  1494.     {
  1495.         /* Let the gadget know that there is an image */
  1496.         SetGadgetAttrs (gad, win, NULL,
  1497.                 GA_LABELIMAGE, im, TAG_DONE);
  1498.     }
  1499.     }
  1500.     else
  1501.     {
  1502.     /* Update the imagry to show the program name */
  1503.     if (APSHGetGadgetInfo (ai, "About", "Icon",
  1504.                    (ULONG *) & win, (ULONG *) & gad))
  1505.     {
  1506.         /* Let the gadget know that there is an image */
  1507.         SetGadgetAttrs (gad, win, NULL,
  1508.                 GA_TEXT, ai->ai_ProgName, TAG_DONE);
  1509.     }
  1510.     }
  1511. }
  1512.  
  1513. VOID
  1514. OpenAboutFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  1515. {
  1516. }
  1517.  
  1518. VOID
  1519. QuitFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  1520. {
  1521.  
  1522.     /* We're all done */
  1523.     ai->ai_Done = TRUE;
  1524. }
  1525.  
  1526. VOID
  1527. CutFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  1528. {
  1529.  
  1530.     /* Set the wait pointer */
  1531.     APSHSetWaitPointer (ai, NULL);
  1532.  
  1533.     /* Copy the contents to the clipboard */
  1534.     CopyFunc (h, ai, af);
  1535.  
  1536.     /* Able to copy? */
  1537.     if (ai->ai_Pri_Ret == RETURN_OK)
  1538.     {
  1539.     /* Erase the image */
  1540.     EraseFunc (h, ai, af);
  1541.     }
  1542.  
  1543.     /* clear the wait pointer */
  1544.     APSHClearPointer (ai, NULL);
  1545. }
  1546.  
  1547. VOID
  1548. CopyFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  1549. {
  1550.     struct AppData *ad = (struct AppData *) ai->ai_UserData;
  1551.     struct IFFHandle *iff;
  1552.     ULONG type, id;
  1553.  
  1554.     /* Just to open the clipboard unit */
  1555.     QueryClip (ad->ad_CM, ad->ad_Unit, (ULONG *) & type, (ULONG *) & id);
  1556.  
  1557.     /* Get a handle on the IFF */
  1558.     if (iff = ad->ad_CM->cm_Unit[ad->ad_Unit])
  1559.     {
  1560.     if (ad->ad_IR)
  1561.     {
  1562.         if (!(PutILBM (ad->ad_CM->cm_Unit[ad->ad_Unit], ad->ad_IR)))
  1563.         {
  1564.         /* Notify user unable to write brush */
  1565.         ai->ai_Pri_Ret = RETURN_ERROR;
  1566.         ai->ai_Sec_Ret = IERR_CANT_LOAD_BRUSH;
  1567.         ai->ai_TextRtn =
  1568.           PrepText (ai, APSH_USER_ID, IERR_CANT_WRITE_BRUSH, NULL);
  1569.         }
  1570.     }
  1571.     else
  1572.     {
  1573.         /* Notify user no brush available */
  1574.         ai->ai_Pri_Ret = RETURN_ERROR;
  1575.         ai->ai_Sec_Ret = IERR_NO_BRUSH;
  1576.         ai->ai_TextRtn =
  1577.           PrepText (ai, APSH_USER_ID, IERR_NO_BRUSH, NULL);
  1578.     }
  1579.     }
  1580.     else
  1581.     {
  1582.     /* Notify user unable to open clipboard */
  1583.     ai->ai_Pri_Ret = RETURN_FAIL;
  1584.     ai->ai_Sec_Ret = IERR_NO_CLIPBOARD;
  1585.     ai->ai_TextRtn =
  1586.       PrepText (ai, APSH_USER_ID, IERR_NO_CLIPBOARD, NULL);
  1587.     }
  1588.  
  1589.     /* clear the wait pointer */
  1590.     APSHClearPointer (ai, NULL);
  1591. }
  1592.  
  1593. VOID
  1594. PasteFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  1595. {
  1596.     struct AppData *ad = (struct AppData *) ai->ai_UserData;
  1597.     struct IFFHandle *iff;
  1598.     ULONG type, id;
  1599.  
  1600.     /* Set the busy pointer */
  1601.     APSHSetWaitPointer (ai, NULL);
  1602.  
  1603.     /* See if there is an ILBM in the clipboard */
  1604.     QueryClip (ad->ad_CM, ad->ad_Unit, (ULONG *) & type, (ULONG *) & id);
  1605.  
  1606.     /* Get a handle on the IFF */
  1607.     if (iff = ad->ad_CM->cm_Unit[ad->ad_Unit])
  1608.     {
  1609.     /* Do we have an ILBM in there? */
  1610.     if (type == ID_ILBM)
  1611.     {
  1612.         struct Window *win = NULL;
  1613.  
  1614.         /* Get a pointer to the window */
  1615.         APSHGetWindowInfo (ai, "Main", (ULONG *) & win);
  1616.  
  1617.         /* Free any existing graphics */
  1618.         FreeGraphic (h, ai, af);
  1619.  
  1620.         /* Read the ILBM record into memory */
  1621.         if (ad->ad_IR = GetILBM (ad->ad_CM->cm_Unit[ad->ad_Unit]))
  1622.         {
  1623.         /* Make an Image out of the bitmap */
  1624.         MakeImage (&(ad->ad_Image), ad->ad_IR);
  1625.  
  1626.         /* Make a pointer out of the bitmap */
  1627.         ad->ad_Ptr = MakePointer (ad->ad_IR);
  1628.         }
  1629.         else
  1630.         {
  1631.         /* Couldn't read brush from clipboard */
  1632.         ai->ai_Pri_Ret = RETURN_ERROR;
  1633.         ai->ai_Sec_Ret = IERR_NO_BRUSH;
  1634.         ai->ai_TextRtn =
  1635.           PrepText (ai, APSH_USER_ID, IERR_CANT_LOAD_BRUSH, NULL);
  1636.         }
  1637.  
  1638.         /* Redraw the graphic */
  1639.         OpenMainFunc (h, ai, af);
  1640.     }
  1641.     else
  1642.     {
  1643.         /* Tell user it isn't an ILBM in there... */
  1644.         ai->ai_Pri_Ret = RETURN_ERROR;
  1645.         ai->ai_Sec_Ret = IERR_NO_BRUSH;
  1646.         ai->ai_TextRtn =
  1647.           PrepText (ai, APSH_USER_ID, IERR_NO_BRUSH, NULL);
  1648.     }
  1649.     }
  1650.     else
  1651.     {
  1652.     /* Notify user unable to open clipboard */
  1653.     ai->ai_Pri_Ret = RETURN_FAIL;
  1654.     ai->ai_Sec_Ret = IERR_NO_CLIPBOARD;
  1655.     ai->ai_TextRtn =
  1656.       PrepText (ai, APSH_USER_ID, IERR_NO_CLIPBOARD, NULL);
  1657.     }
  1658.  
  1659.     /* clear the wait pointer */
  1660.     APSHClearPointer (ai, NULL);
  1661. }
  1662.  
  1663. VOID
  1664. EraseFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  1665. {
  1666.  
  1667.     /* Set the busy pointer */
  1668.     APSHSetWaitPointer (ai, NULL);
  1669.  
  1670.     /* Free any existing graphics */
  1671.     FreeGraphic (h, ai, af);
  1672.  
  1673.     /* Redraw the graphic */
  1674.     OpenMainFunc (h, ai, af);
  1675.  
  1676.     /* clear the wait pointer */
  1677.     APSHClearPointer (ai, NULL);
  1678. }
  1679.  
  1680. VOID ClipChangeFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  1681. {
  1682.     struct AppData *ad = (struct AppData *) ai->ai_UserData;
  1683.     ULONG type, id;
  1684.  
  1685.     /* See what is in the clipboard */
  1686.     QueryClip (ad->ad_CM, ad->ad_Unit, (ULONG *) & type, (ULONG *) & id);
  1687.  
  1688.     /* What type are the contents? */
  1689.     if (type == ID_ILBM)
  1690.     {
  1691.     /* Enable the Paste function no matter what */
  1692.     PerfFunc (ai, NULL, "enable paste force", NULL);
  1693.     }
  1694.     else
  1695.     {
  1696.     /* Disable the Paste function */
  1697.     PerfFunc (ai, NULL, "disable paste", NULL);
  1698.     }
  1699. }
  1700.  
  1701. /* This gets called when a Workbench or AppShell icon is dropped on it */
  1702. VOID
  1703. DropIconFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  1704. {
  1705.     struct AppData *ad = (struct AppData *) ai->ai_UserData;
  1706.     struct TagItem *attrs = af->af_Attrs;
  1707.     struct DiskObject *dob = NULL;
  1708.     struct Image *im = NULL;
  1709.     struct ObjectNode *on;
  1710.     struct WBArg *wbarg;
  1711.  
  1712.     if (wbarg = (struct WBArg *) GetTagData (APSH_WBArg, NULL, attrs))
  1713.     {
  1714.     BPTR lock;
  1715.  
  1716.     /* Go to the directory represented by the icon */
  1717.     if (lock = CurrentDir (wbarg->wa_Lock))
  1718.     {
  1719.         /* Get the name of the directory */
  1720.         NameFromLock (wbarg->wa_Lock, ad->ad_Tmp, 510);
  1721.         AddPart (ad->ad_Tmp, wbarg->wa_Name, 510);
  1722.  
  1723.         /* Free any existing graphics */
  1724.         FreeGraphic (h, ai, af);
  1725.  
  1726.         /* Read the ILBM record into memory */
  1727.         if (ad->ad_IR = ReadILBM (NULL, ad->ad_Tmp, NULL))
  1728.         {
  1729.         /* Make an Image out of the bitmap */
  1730.         MakeImage (&(ad->ad_Image), ad->ad_IR);
  1731.  
  1732.         /* Make a pointer out of the bitmap */
  1733.         ad->ad_Ptr = MakePointer (ad->ad_IR);
  1734.  
  1735.         /* We have a name */
  1736.         strcpy (ad->ad_Name, ad->ad_Tmp);
  1737.         }
  1738.         else
  1739.         {
  1740.         /* Notify user unable to load brush */
  1741.         ai->ai_Pri_Ret = RETURN_ERROR;
  1742.         ai->ai_Sec_Ret = IERR_CANT_LOAD_BRUSH;
  1743.         ai->ai_TextRtn =
  1744.           PrepText (ai, APSH_USER_ID, IERR_CANT_LOAD_BRUSH, NULL);
  1745.         }
  1746.  
  1747.         /* Refresh the display */
  1748.         OpenMainFunc (h, ai, af);
  1749.  
  1750.         /* Go back home */
  1751.         CurrentDir (lock);
  1752.     }
  1753.  
  1754.     /* Set the real file name */
  1755.     FixFileAndPath (ad->ad_FR[FR_ILBM], ad->ad_Name);
  1756.     }
  1757.     else if (on = (struct ObjectNode *)
  1758.          GetTagData (APSH_MsgIAddress, NULL, attrs))
  1759.     {
  1760.     struct Gadget *gad = on->on_Gadget;
  1761.  
  1762.     if (gad->GadgetText)
  1763.     {
  1764.         WORD label = (gad->Flags & LABELMASK);
  1765.  
  1766.         if (label == LABELIMAGE)
  1767.         {
  1768.         im = (struct Image *) gad->GadgetText;
  1769.         }
  1770.     }
  1771.     else if (gad->Flags & GADGIMAGE)
  1772.     {
  1773.         im = (struct Image *) gad->GadgetRender;
  1774.     }
  1775.     }
  1776.  
  1777.     /* Do we have an image, and is somebody other than ourself? */
  1778.     if (im && (im != &(ad->ad_Image)))
  1779.     {
  1780.     struct Window *win;
  1781.     struct Gadget *gad;
  1782.  
  1783.     /* Free any existing graphics */
  1784.     FreeGraphic (h, ai, af);
  1785.  
  1786.     /* Copy the image over */
  1787.     CopyImage (im, &(ad->ad_Image));
  1788.  
  1789.     /* Refresh the pointer */
  1790.     im = &(ad->ad_Image);
  1791.  
  1792.     /* Update the imagry */
  1793.     if (APSHGetGadgetInfo (ai, "Main", "Display",
  1794.                    (ULONG *) & win, (ULONG *) & gad))
  1795.     {
  1796.         /* Let the gadget know that there is an image */
  1797.         SetGadgetAttrs (gad, win, NULL, GA_LABELIMAGE, im, TAG_DONE);
  1798.     }
  1799.     }
  1800.  
  1801.     if (dob)
  1802.     {
  1803.     FreeDiskObject (dob);
  1804.     }
  1805. }
  1806.  
  1807. VOID
  1808. SetNameFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  1809. {
  1810.     struct AppData *ad = (struct AppData *) ai->ai_UserData;
  1811.     struct TagItem *attrs = af->af_Attrs;
  1812.     struct Window *win;
  1813.     struct Gadget *gad;
  1814.     struct Funcs *f;
  1815.     STRPTR name = NULL;
  1816.  
  1817.     if (f = af->af_FE)
  1818.     {
  1819.     /* See if they passed a file name */
  1820.     name = (STRPTR) f->fe_Options[0];
  1821.     }
  1822.     else
  1823.     {
  1824.     /* See if they passed a name with a tag */
  1825.     name = (STRPTR) GetTagData (APSH_NameTag, NULL, attrs);
  1826.     }
  1827.  
  1828.     /* Update the gadget */
  1829.     if (APSHGetGadgetInfo (ai, "Main", "Name",
  1830.                (ULONG *) & win, (ULONG *) & gad))
  1831.     {
  1832.     if (name)
  1833.     {
  1834.         /* Update the string gadget */
  1835.         GT_SetGadgetAttrs (gad, win, NULL,
  1836.                    GTST_String, name,
  1837.                    TAG_DONE);
  1838.     }
  1839.     else
  1840.     {
  1841.         name = (STRPTR) (((struct StringInfo *) gad->SpecialInfo)->Buffer);
  1842.     }
  1843.     }
  1844.  
  1845.     /* Do we have a value? */
  1846.     if (name)
  1847.     {
  1848.     /* Update the field */
  1849.     strcpy (ad->ad_Struct, name);
  1850.     }
  1851. }
  1852.  
  1853. VOID
  1854. SetModeFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  1855. {
  1856.     struct AppData *ad = (struct AppData *) ai->ai_UserData;
  1857.     struct TagItem *attrs = af->af_Attrs;
  1858.     struct TagItem *tag;
  1859.     struct Gadget *gad;
  1860.     struct Window *win;
  1861.     LONG mode = (-1);
  1862.     struct Funcs *f;
  1863.  
  1864.     if (f = af->af_FE)
  1865.     {
  1866.     if (f->fe_Options[0])
  1867.     {
  1868.         ad->ad_Mode = mode = 0;
  1869.     }
  1870.     else if (f->fe_Options[1])
  1871.     {
  1872.         ad->ad_Mode = mode = 1;
  1873.     }
  1874.     else if (f->fe_Options[2])
  1875.     {
  1876.         ad->ad_Mode = mode = 2;
  1877.     }
  1878.     }
  1879.     /* Being set from the gadget */
  1880.     else if (tag = FindTagItem (APSH_MsgCode, attrs))
  1881.     {
  1882.     ad->ad_Mode = tag->ti_Data;
  1883.     }
  1884.  
  1885.     /* Update the gadget */
  1886.     if ((mode >= 0) &&
  1887.     (APSHGetGadgetInfo (ai, "Main", "Mode", (ULONG *) & win, (ULONG *) & gad)))
  1888.     {
  1889.     /* Update the string gadget */
  1890.     GT_SetGadgetAttrs (gad, win, NULL, GTCY_Active, mode, TAG_DONE);
  1891.     }
  1892.  
  1893.     /* clear the wait pointer */
  1894.     APSHClearPointer (ai, NULL);
  1895. }
  1896.  
  1897. /*
  1898.  * For now, simply masks out new modes. This may be invalid in future.
  1899.  * Should search the display database for a suitable mode...
  1900.  *
  1901.  * Written by: Carolyn Scheppner
  1902.  */
  1903.  
  1904. #define MODE_ID_MASK (LACE|HIRES|HAM|EXTRA_HALFBRITE)
  1905.  
  1906. ULONG
  1907. modefallback (ULONG mode, SHORT wide, SHORT high, SHORT deep)
  1908. {
  1909.     ULONG newmode;
  1910.  
  1911.     newmode = mode & MODE_ID_MASK;
  1912.     return (newmode);
  1913. }
  1914.  
  1915. /*
  1916.  * clipit - passed width and height of a display, and the
  1917.  *          text, std, and max overscan rectangles for the mode,
  1918.  *          clipit fills in spos (screen pos) and dclip rectangles
  1919.  *          to use in centering the display like the user's std oscan
  1920.  *          prefs, with dclip confined to legal maxoscan limits.
  1921.  *          Screens which center such that their top is below text
  1922.  *          oscan top, will be moved up.
  1923.  *          If a non-null uclip is passed, that clip is used instead.
  1924.  *
  1925.  * Written by: Carolyn Scheppner
  1926.  */
  1927. VOID
  1928. clipit (SHORT wide, SHORT high,
  1929.     struct Rectangle * spos, struct Rectangle * dclip,
  1930.     struct Rectangle * txto, struct Rectangle * stdo,
  1931.     struct Rectangle * maxo, struct Rectangle * uclip)
  1932. {
  1933.     SHORT minx, maxx, miny, maxy;
  1934.     SHORT stdw, stdh, maxw, maxh;
  1935.  
  1936.     /* get the std and max widths and heights */
  1937.     stdw = stdo->MaxX - stdo->MinX + 1;
  1938.     stdh = stdo->MaxY - stdo->MinY + 1;
  1939.     maxw = maxo->MaxX - maxo->MinX + 1;
  1940.     maxh = maxo->MaxY - maxo->MinY + 1;
  1941.  
  1942.     if (uclip)
  1943.     {
  1944.     *dclip = *uclip;
  1945.     spos->MinX = uclip->MinX;
  1946.     spos->MinY = uclip->MinY;
  1947.     }
  1948.     else
  1949.     {
  1950.  
  1951.     /*
  1952.      * CENTER the screen based on stdoscan prefs but confine dclip within
  1953.      * max oscan limits
  1954.      *
  1955.      * FIX MinX first
  1956.      */
  1957.     spos->MinX = minx = stdo->MinX - ((wide - stdw) >> 1);
  1958.     maxx = wide + minx - 1;
  1959.     if (maxx > maxo->MaxX)
  1960.         maxx = maxo->MaxX;    /* too right */
  1961.     if (minx < maxo->MinX)
  1962.         minx = maxo->MinX;    /* too left  */
  1963.  
  1964.     /* FIX MinY */
  1965.     spos->MinY = miny = stdo->MinY - ((high - stdh) >> 1);
  1966.     /* if lower than top of txto, move up */
  1967.     spos->MinY = miny = MIN (spos->MinY, txto->MinY);
  1968.     maxy = high + miny - 1;
  1969.     if (maxy > maxo->MaxY)
  1970.         maxy = maxo->MaxY;    /* too down  */
  1971.     if (miny < maxo->MinY)
  1972.         miny = maxo->MinY;    /* too up    */
  1973.  
  1974.     /* SET up dclip */
  1975.     dclip->MinX = minx;
  1976.     dclip->MinY = miny;
  1977.     dclip->MaxX = maxx;
  1978.     dclip->MaxY = maxy;
  1979.  
  1980.     }
  1981. }
  1982.  
  1983. struct Screen *
  1984. OpenILBMScreen (struct AppInfo * ai, struct NewScreen * ns, ILBM * ir)
  1985. {
  1986.     struct Screen *scr = NULL;
  1987.  
  1988.     /* See if we have an bitmap to display */
  1989.     if (ir)
  1990.     {
  1991.     struct TagItem tag[15];
  1992.     LONG mode = ir->ir_ModeID;
  1993.     WORD w = ir->ir_Width;
  1994.     WORD h = ir->ir_Height;
  1995.     WORD d = ir->ir_Depth;
  1996.     struct Rectangle spos, dclip, txto, stdo, maxo;
  1997.     LONG error, trynew;
  1998.  
  1999.     /* See if the screen mode is available */
  2000.     if (error = ModeNotAvailable (mode))
  2001.     {
  2002.         /* If not available, try fall back mode */
  2003.         mode = modefallback (mode, w, h, d);
  2004.  
  2005.         /* See if the new mode is available */
  2006.         error = ModeNotAvailable (mode);
  2007.     }
  2008.  
  2009.     /* Were we able to come up with a ModeID? */
  2010.     if (error)
  2011.     {
  2012.         trynew = FALSE;
  2013.     }
  2014.     else
  2015.     {
  2016.         trynew = ((QueryOverscan (mode, &txto, OSCAN_TEXT)) &&
  2017.               (QueryOverscan (mode, &stdo, OSCAN_STANDARD)) &&
  2018.               (QueryOverscan (mode, &maxo, OSCAN_MAX)));
  2019.     }
  2020.  
  2021.     /* Fill out the tags */
  2022.     tag[0].ti_Tag = SA_DisplayID;
  2023.     tag[0].ti_Data = (LONG) mode;
  2024.     tag[1].ti_Tag = TAG_IGNORE;
  2025.     tag[2].ti_Tag = TAG_IGNORE;
  2026.     tag[3].ti_Tag = SA_Width;
  2027.     tag[3].ti_Data = (LONG) w;
  2028.     tag[4].ti_Tag = SA_Height;
  2029.     tag[4].ti_Data = (LONG) h;
  2030.     tag[5].ti_Tag = SA_Depth;
  2031.     tag[5].ti_Data = (LONG) d;
  2032.     tag[6].ti_Tag = TAG_IGNORE;
  2033.     tag[7].ti_Tag = SA_Quiet;
  2034.     tag[7].ti_Data = (LONG) TRUE;
  2035.     tag[8].ti_Tag = SA_AutoScroll;
  2036.     tag[8].ti_Data = (LONG) TRUE;
  2037.     tag[9].ti_Tag = SA_FullPalette;
  2038.     tag[9].ti_Data = (LONG) TRUE;
  2039.     tag[10].ti_Tag = SA_BitMap;
  2040.     tag[10].ti_Data = (LONG) & (ir->ir_BMap);
  2041.     tag[11].ti_Tag = SA_ErrorCode;
  2042.     tag[11].ti_Data = (LONG) & error,
  2043.       tag[12].ti_Tag = TAG_DONE;
  2044.  
  2045.     /* Are we going to try opening based on the clips? */
  2046.     if (trynew)
  2047.     {
  2048.         clipit (w, h, &spos, &dclip, &txto, &stdo, &maxo, NULL);
  2049.  
  2050.         tag[1].ti_Tag = SA_Top;
  2051.         tag[1].ti_Data = spos.MinY;
  2052.         tag[2].ti_Tag = SA_Left;
  2053.         tag[2].ti_Data = spos.MinX;
  2054.         tag[6].ti_Tag = SA_DClip;
  2055.         tag[6].ti_Data = (LONG) & dclip;
  2056.     }
  2057.  
  2058.     /* Open up that screen */
  2059.     if (scr = OpenScreenTagList (NULL, tag))
  2060.     {
  2061.         /* Set the screen colors */
  2062.         LoadRGB4 (&(scr->ViewPort), ir->ir_CRegs, ir->ir_NumColors);
  2063.     }
  2064.     else
  2065.     {
  2066.         /* Unable to open the screen */
  2067.         ai->ai_Pri_Ret = RETURN_ERROR;
  2068.         ai->ai_Sec_Ret = (error + (IERR_NOMONITOR - 1));
  2069.         ai->ai_TextRtn =
  2070.           PrepText (ai, APSH_USER_ID, ai->ai_Sec_Ret, NULL);
  2071.     }
  2072.     }
  2073.     else
  2074.     {
  2075.     /* No image loaded */
  2076.     ai->ai_Pri_Ret = RETURN_ERROR;
  2077.     ai->ai_Sec_Ret = IERR_NO_BRUSH;
  2078.     ai->ai_TextRtn =
  2079.       PrepText (ai, APSH_USER_ID, IERR_NO_BRUSH, NULL);
  2080.     }
  2081.  
  2082.     return (scr);
  2083. }
  2084.  
  2085. VOID DisplayFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  2086. {
  2087.     struct AppData *ad = (struct AppData *) ai->ai_UserData;
  2088.     ILBM *ir = ad->ad_IR;
  2089.     struct Window *win;
  2090.     struct Funcs *f;
  2091.     BOOL close;
  2092.  
  2093.     /* See if we have a parsed command */
  2094.     if (f = af->af_FE)
  2095.     {
  2096.     /* See if they passed a file name */
  2097.     close = (BOOL) f->fe_Options[0];
  2098.     }
  2099.  
  2100.     /* Get a pointer to the window */
  2101.     APSHGetWindowInfo (ai, "Main", (ULONG *) & win);
  2102.  
  2103.     /* Set the pointer back to normal */
  2104.     APSHClearPointer (ai, NULL);
  2105.  
  2106.     /* Close the display? */
  2107.     if (close)
  2108.     {
  2109.     /* Is the screen open? */
  2110.     if (ad->ad_Screen)
  2111.     {
  2112.         /* Close the Screen.  Bug? in Intuition clears the bitmap. */
  2113.         CloseScreen (ad->ad_Screen);
  2114.         ad->ad_Screen = NULL;
  2115.     }
  2116.     }
  2117.     /* Open the display */
  2118.     else
  2119.     {
  2120.     switch (ad->ad_Mode)
  2121.     {
  2122.         case ICON:
  2123.         case IMAGE:
  2124.         if (ir && (ad->ad_Screen == NULL))
  2125.         {
  2126.             ad->ad_Screen = OpenILBMScreen (ai, NULL, ad->ad_IR);
  2127.         }
  2128.  
  2129.         /* Is the screen open? */
  2130.         if (ad->ad_Screen)
  2131.         {
  2132.             /* Bring it to front */
  2133.             ScreenToFront (ad->ad_Screen);
  2134.         }
  2135.         break;
  2136.  
  2137.         case SPRITE:
  2138.         if (win)
  2139.         {
  2140.             struct PointerPref *pp = ad->ad_Ptr;
  2141.  
  2142.             /* Set the pointer */
  2143.             SetPointer (win, pp->pp_PData, pp->pp_Height, pp->pp_Width,
  2144.                 pp->pp_XOffset, pp->pp_YOffset);
  2145.         }
  2146.         else
  2147.         {
  2148.         }
  2149.         break;
  2150.     }
  2151.     }
  2152. }
  2153.  
  2154. VOID
  2155. SaveSettingsFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
  2156. {
  2157. }
  2158.  
  2159. UWORD chip listingI1Data[] =
  2160. {
  2161. /* Plane 0 */
  2162.     0x0000, 0x0000, 0x0000, 0x0400, 0x0000, 0x0000, 0x0000, 0x0C00,
  2163.     0x0000, 0x0000, 0x0000, 0x0C00, 0x0FFF, 0xFFFF, 0xFFE0, 0x0C00,
  2164.     0x0800, 0x0000, 0x0030, 0x0C00, 0x0980, 0x0000, 0x0028, 0x0C00,
  2165.     0x0800, 0x0000, 0x0024, 0x0C00, 0x098A, 0xA000, 0x0022, 0x0C00,
  2166.     0x0800, 0x0000, 0x003F, 0x0C00, 0x098A, 0xA800, 0x000C, 0x8C00,
  2167.     0x0800, 0x0000, 0x0000, 0x8C00, 0x0980, 0x2AAA, 0xA80C, 0x8C00,
  2168.     0x0800, 0x0000, 0x0000, 0x8C00, 0x0980, 0x2AAA, 0xA00C, 0x8C00,
  2169.     0x0800, 0x0000, 0x0000, 0x8C00, 0x098A, 0xA800, 0x000C, 0x8C00,
  2170.     0x0800, 0x0000, 0x0000, 0x8C00, 0x098A, 0x0000, 0x000C, 0x8C00,
  2171.     0x0FFF, 0xFFFF, 0xFFFF, 0x8C00, 0x0000, 0x0000, 0x0000, 0x0C00,
  2172.     0x0000, 0x0000, 0x0000, 0x0C00, 0x7FFF, 0xFFFF, 0xFFFF, 0xFC00,
  2173. /* Plane 1 */
  2174.     0xFFFF, 0xFFFF, 0xFFFF, 0xF800, 0xD555, 0x5555, 0x5555, 0x5000,
  2175.     0xD555, 0x5555, 0x5555, 0x5000, 0xD000, 0x0000, 0x0015, 0x5000,
  2176.     0xD7FF, 0xFFFF, 0xFFC5, 0x5000, 0xD67F, 0xFFFF, 0xFFD5, 0x5000,
  2177.     0xD7FF, 0xFFFF, 0xFFD9, 0x5000, 0xD675, 0x5FFF, 0xFFDD, 0x5000,
  2178.     0xD7FF, 0xFFFF, 0xFFC0, 0x5000, 0xD675, 0x57FF, 0xFFF3, 0x5000,
  2179.     0xD7FF, 0xFFFF, 0xFFFF, 0x5000, 0xD67F, 0xD555, 0x57F3, 0x5000,
  2180.     0xD7FF, 0xFFFF, 0xFFFF, 0x5000, 0xD67F, 0xD555, 0x5FF3, 0x5000,
  2181.     0xD7FF, 0xFFFF, 0xFFFF, 0x5000, 0xD675, 0x57FF, 0xFFF3, 0x5000,
  2182.     0xD7FF, 0xFFFF, 0xFFFF, 0x5000, 0xD675, 0xFFFF, 0xFFF3, 0x5000,
  2183.     0xD000, 0x0000, 0x0000, 0x5000, 0xD555, 0x5555, 0x5555, 0x5000,
  2184.     0xD555, 0x5555, 0x5555, 0x5000, 0x8000, 0x0000, 0x0000, 0x0000,
  2185. };
  2186.  
  2187. struct Image listingI1 =
  2188. {
  2189.     0, 0,            /* Upper left corner */
  2190.     54, 22, 2,            /* Width, Height, Depth */
  2191.     listingI1Data,        /* Image data */
  2192.     0x0003, 0x0000,        /* PlanePick, PlaneOnOff */
  2193.     NULL            /* Next image */
  2194. };
  2195.  
  2196. struct DiskObject Listing =
  2197. {
  2198.     WB_DISKMAGIC,        /* Magic Number */
  2199.     WB_DISKVERSION,        /* Version */
  2200.     {                /* Embedded Gadget Structure */
  2201.     NULL,            /* Next Gadget Pointer */
  2202.     0, 0, 54, 23,        /* Left,Top,Width,Height */
  2203.     GADGIMAGE | GADGHCOMP,    /* Flags */
  2204.     RELVERIFY,        /* Activation Flags */
  2205.     BOOLGADGET,        /* Gadget Type */
  2206.     (APTR) & listingI1,    /* Render Image */
  2207.     NULL,            /* Select Image */
  2208.     NULL,            /* Gadget Text */
  2209.     NULL,            /* Mutual Exclude */
  2210.     NULL,            /* Special Info */
  2211.     0,            /* Gadget ID */
  2212.     NULL,            /* User Data */
  2213.     },
  2214.     WBPROJECT,            /* Icon Type */
  2215.     (char *) "Ed",        /* Default Tool */
  2216.     NULL,            /* Tool Type Array */
  2217.     NO_ICON_POSITION,        /* Current X */
  2218.     NO_ICON_POSITION,        /* Current Y */
  2219.     NULL,            /* Drawer Structure */
  2220.     NULL,            /* Tool Window */
  2221.     0                /* Stack Size */
  2222. };
  2223.